#include "driver/usb_serial_jtag.h"
#include "usb_public.h"
#include "usbd_core.h"
#include "work_status_setting.h"
#include "dap_usb_handle.h"
#include "msc.h"
#include "esp_jtag_main.h"
#include "esp_log.h"
#include "logic_analyzer_cdc.h"
#include "disk_main.h"
#include "usb_ext_screen.h"

static const char *TAG = "usb_public";
struct usb_msosv2_descriptor msosv2_desc = {
    .vendor_code = USBD_WINUSB_VENDOR_CODE,
    .compat_id = USBD_WinUSBDescriptorSetDescriptor,
    .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};

struct usb_bos_descriptor bos_desc = {
    .string = USBD_BinaryObjectStoreDescriptor,
    .string_len = USBD_BOS_WTOTALLENGTH
};
static const uint8_t usb_device_descriptor_default[] = {
    USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, BRIDGE_USB_VID, BRIDGE_USB_PID, 0x0200, 0x01),
};
static const uint8_t usb_device_quality_descriptor_default[] = {
    //0xEF专为复合设备 设计需配合 IAD 描述符使用，兼容性更好（Windows / Linux 无需额外驱动
    //0x00通常用于复合设备，类信息由接口描述符（bInterfaceClass）单独定义
    USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, 0x01),
};
//设备描述符回调函数
__WEAK const uint8_t *usb_device_descriptor_callback_default(uint8_t speed)
{
    (void)speed;
    return usb_device_descriptor_default;
}
//设备质量描述符回调函数
__WEAK const uint8_t *usb_device_quality_descriptor_callback_default(uint8_t speed)
{
    (void)speed;
    return usb_device_quality_descriptor_default;
}
/**
 * @brief USB设备事件处理函数
 * @param busid USB总线标识符（未使用）
 * @param event 触发的事件类型
 */
void usbd_event_handler(uint8_t busid, uint8_t event)
{
    (void)busid;               // 显式忽略未使用的参数
    work_status_t work_status; // 定义工作状态变量

    switch (event) {
        case USBD_EVENT_RESET:               // USB复位事件（主机发起复位）
            work_status = get_work_status(); // 获取当前工作模式
            switch (work_status) {
                case DAP_WORK:                // 如果是DAP模式（调试适配器模式）
                dap_usbd_event_rst();
                    break;
                default:
                    break;
            }
            break;

        case USBD_EVENT_CONNECTED: // USB连接事件（设备插入主机）
            break;                 // 默认不处理

        case USBD_EVENT_DISCONNECTED: // USB断开事件（设备从主机移除）
            break;                    // 默认不处理

        case USBD_EVENT_RESUME: // USB唤醒事件（从挂起状态恢复）
            break;              // 默认不处理

        case USBD_EVENT_SUSPEND: // USB挂起事件（主机进入节能模式）
            break;               // 默认不处理

        case USBD_EVENT_CONFIGURED:          // USB配置完成事件（主机成功配置设备）
            work_status = get_work_status(); // 获取当前工作模式
            switch (work_status) {
                case DAP_WORK:            // 如果是DAP模式
                    dap_usbd_event_cfg();
                    break;
                case ESP_JTAG_WORK:       // 如果是JTAG模式
                    usbjtag_usbd_event_cfg();
                    break;
                case LOGIC_WORK: // 如果是逻辑分析仪模式
                    logic_usbd_event_cfg();
                    break;
                case USB_EXT_SCREEN_WORK: // 如果是usb副屏模式
                    usb_ext_screen_usbd_event_cfg();
                    break;
                default:
                    break;
            }
            break;

        case USBD_EVENT_SET_REMOTE_WAKEUP: // 主机启用远程唤醒功能
            break;                         // 默认不处理

        case USBD_EVENT_CLR_REMOTE_WAKEUP: // 主机禁用远程唤醒功能
            break;                         // 默认不处理

        default: // 未知事件类型
            break;
    }
}

// MSC获取磁盘容量回调
void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
{
    work_status_t work_status = get_work_status(); // 获取当前工作模式
    work_status = get_work_status();               // 获取当前工作模式
    if (lun <= MSC_MAX_LUN)
    {
        switch (work_status) {
            case MSC_WIFI_DISK_WORK: // 如果是MSC模式/无线网盘模式
                *block_num = msc_wifi_disk_get_sector_count(); // 获取总扇区数
                *block_size = msc_wifi_disk_get_sector_size(); // 获取扇区大小
                break;
            case ESP_JTAG_WORK:                          // 如果是JTAG模式
                *block_num = bootuf2_get_sector_count(); // 获取总扇区数
                *block_size = bootuf2_get_sector_size(); // 获取扇区大小
                break;
            default:
                break;
        }

        ESP_LOGE(TAG, "sector count:%d, sector size:%d\n", *block_num, *block_size);
    }

}

// MSC读取扇区回调
int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
    if (lun > MSC_MAX_LUN)
        return 0;
    work_status_t work_status = get_work_status(); // 获取当前工作模式
    work_status = get_work_status();               // 获取当前工作模式
    //ESP_LOGI("MdLink", "call usbd_msc_sector_read() mode:%d", work_status);
    //ESP_EARLY_LOGI("MdLink", "call usbd_msc_sector_read() mode:%d", work_status);
    switch (work_status) {
        case MSC_WIFI_DISK_WORK: // 如果是MSC模式/无线网盘模式
            msc_wifi_disk_read_sector(sector, buffer, length);
            break;
        case ESP_JTAG_WORK:                          // 如果是espJTAG模式
            boot2uf2_read_sector(sector, buffer, length / bootuf2_get_sector_size());
            break;
        default:
            break;
    }
    return 0;
}

// MSC写入扇区回调（处理UF2格式数据）
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
    if (lun > MSC_MAX_LUN)
        return 0;
    work_status_t work_status = get_work_status(); // 获取当前工作模式
    work_status = get_work_status();               // 获取当前工作模式
    switch (work_status) {
        case MSC_WIFI_DISK_WORK: // 如果是MSC模式/无线网盘模式
            msc_wifi_disk_write_sector(sector, buffer, length);
            break;
        case ESP_JTAG_WORK: // 如果是espJTAG模式
            return bootuf2_write_sector(sector, buffer, length / bootuf2_get_sector_size());
        default:
            break;
    }
    return 0;
}

/**
 * @brief 重新使能 USB Serial/JTAG 接口（含JTAG功能）
 * @note 严格匹配 ESP-IDF v5.2 的驱动API
 */
void usb_esp_jtag_serial_enable(void)
{
    // 1. 卸载现有驱动（忽略 ESP_ERR_NOT_FOUND 错误）
    esp_err_t ret = usb_serial_jtag_driver_uninstall();
    if (ret != ESP_OK && ret != ESP_ERR_NOT_FOUND) {
        ESP_LOGE("USB_JTAG", "Driver uninstall failed: %s", esp_err_to_name(ret));
        return;
    }

    // 2. 使用默认配置安装驱动（缓冲区大小256字节）
    usb_serial_jtag_driver_config_t config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
    ret = usb_serial_jtag_driver_install(&config);
    if (ret != ESP_OK) {
        ESP_LOGE("USB_JTAG", "Driver install failed: %s", esp_err_to_name(ret));
        return;
    }

    // 3. 确认JTAG功能已激活（依赖底层自动启用）
    ESP_LOGI("USB_JTAG", "USB Serial/JTAG enabled (TX/RX buf: %d bytes)", config.tx_buffer_size);
}